import { useElementSize, useDevicePixelRatio, useManualRefHistory } from "@vueuse/core"
// 公共组件列表
import common from "@/plugins/common.js"
import dayjs from "@/utils/day"
import Router from "@/router"
// 是否开发模式
export const devMode = ref(import.meta.env.MODE === "development")
//初始化缩放比
export const scale = ref(1)
export function useScale(editor) {
  const scaleOptions = [
    {
      content: "50%",
      value: 0.5
    },
    {
      content: "80%",
      value: 0.8
    },
    {
      content: "100%",
      value: 1
    }
  ]
  const handleScaleSelect = (item) => {
    scale.value = item.value
  }
  const { width } = useElementSize(editor)
  // 计算缩放比例方法
  const handleScale = async () => {
    await nextTick()
    scale.value = (width.value / commonStyle.value.width).toFixed(3)
    scale.value = scale.value > 1 ? 1 : scale.value
  }
  watch(
    () => [width.value, commonStyle.value.width],
    () => {
      handleScale()
    }
  )

  return {
    scale,
    scaleOptions,
    handleScaleSelect,
    handleScale
  }
}
// 侧边栏
export const collapsed = ref(true)
export const onCollapse = () => {
  collapsed.value = !collapsed.value
}
export const commonStyle = ref({
  width: 1920,
  height: 1080,
  backgroundColor: "#fff",
  backgroundImage: "",
  //背景位置
  backgroundPosition: "center",
  // 主题
  theme: "dark",
  fontFamily: "",
  // 图表主题
  registerTheme: "",
  //背景缩放方式
  backgroundSize: "cover",
  // 三维透视
  //水印显示
  watermarkShow: false
})
// 获取大屏属性
export const useVisual = () => {
  const visual = ref({
    title: "",
    background_url: ""
  })
  const canvasEditStyle = computed(() => {
    return {
      width: commonStyle.value.width + "px",
      height: commonStyle.value.height + "px",
      transform: `scale(${scale.value})`,
      background: commonStyle.value.backgroundImage
        ? `url(${commonStyle.value.backgroundImage})`
        : commonStyle.value.backgroundColor,
      backgroundPosition: commonStyle.value.backgroundPosition,
      backgroundRepeat: "no-repeat",
      backgroundSize: commonStyle.value.backgroundSize,
      fontFamily: commonStyle.value.fontFamily
    }
  })
  return {
    visual,
    commonStyle,
    canvasEditStyle
  }
}

// 组件列表
export const componentList = ref([])
//选中的组件
export const currentComponent = ref({})
// 组合管理
export const groupManager = ref([])
// 移动组件
let moveableReff = null
export const setMoveableRef = () => {
  const setMoveableReff = (moveableRef) => {
    moveableReff = moveableRef
  }
  return {
    moveableReff,
    setMoveableReff
  }
}
// 操作组件
const componentListRef = {}
import { settings } from "@/plugins/index.js"
export const useComponent = () => {
  // 组件列表
  const getComponent = async (component) => {
    for (const item of component) {
      const setting = settings.value[item.name]
      item.option = deepAssign(setting.option, item.option)
      item.optionSet = []
      if (setting?.optionSet && setting.optionSet.length > 0) {
        item.optionSet = setting.optionSet.map((option) => {
          Object.keys(common[option].options).forEach((key) => {
            if (item.option[key]) {
              item.option[key] = deepAssign(common[option].options[key], item.option[key])
            } else {
              item.option[key] = common[option].options[key]
            }
          })
          return {
            name: option,
            title: common[option].title
          }
        })
      }
      const dataConfigOption = {}
      Object.keys(setting.dataConfigOption).forEach((key) => {
        dataConfigOption[key] = []
      })
      dataConfigOption.sort = []
      dataConfigOption.filter = []
      item.data = {
        ...dataConfigOption,
        ...item.data
      }
      componentList.value.push(g.Copy(item))
    }
  }
  // 重置组件
  const resetComponent = () => {
    const setting = settings.value[currentComponent.value.name]
    Object.keys(setting.dataConfigOption).forEach((key) => {
      currentComponent.value.data[key] = []
    })
    currentComponent.value.data.sort = []
    currentComponent.value.data.filter = []
  }
  // 添加组件
  const addComponent = async (component, left = 0, top = 0) => {
    component = g.Copy(component)
    const key = `${component.name}-${g.guid(12)}`
    const setting = settings.value[component.name]
    let optionSet = []
    const obj = {}
    if (setting.optionSet.length > 0) {
      optionSet = setting.optionSet.map((option) => {
        Object.keys(common[option].options).forEach((key) => {
          obj[key] = common[option].options[key]
        })
        return {
          name: option,
          title: common[option].title
        }
      })
    }
    component.option = deepAssign(obj, setting.option)
    const dataConfigOption = {}
    Object.keys(setting.dataConfigOption).forEach((key) => {
      dataConfigOption[key] = []
    })
    dataConfigOption.sort = []
    dataConfigOption.filter = []
    const item = {
      data: dataConfigOption,
      element: {
        title: component.title,
        width: setting.width,
        height: setting.height,
        left: left || 0,
        top: top || 0,
        rotate: 0,
        //透明度
        opacity: 1,
        zIndex: componentList.value.length + 1,
        perspective: false,
        // 隐藏
        hidden: false,
        // 锁定
        lock: false,
        classStyle: ""
      },
      option: setting.option,
      key
    }
    component = g.Copy({
      ...item,
      ...component,
      ...{ optionSet }
    })
    component.option.horizontal = false
    component.option.label = {
      show: true,
      position: "top",
      distance: 5,
      rotate: 0,
      color: "",
      fontWeight: "normal",
      fontSize: 14,
      overflow: "break"
    }
    componentList.value.push(component)
    selectComponent(component)
  }
  // 导入json
  const importCompoent = (component) => {
    component = g.Copy(component)
    const key = `${component.name}-${g.guid(12)}`
    const setting = settings.value[component.name]
    let optionSet = []
    const obj = {}
    if (setting.optionSet.length > 0) {
      optionSet = setting.optionSet.map((option) => {
        Object.keys(common[option].options).forEach((key) => {
          obj[key] = common[option].options[key]
        })
        return {
          name: option,
          title: common[option].title
        }
      })
    }
    component.option = { ...obj, ...setting.option, ...component.option }
    const dataConfigOption = {}
    Object.keys(setting.dataConfigOption).forEach((key) => {
      dataConfigOption[key] = []
    })
    dataConfigOption.sort = []
    dataConfigOption.filter = []
    const item = {
      data: dataConfigOption,
      element: {
        title: component.title,
        width: component.site.w,
        height: component.site.h,
        left: component.site.x,
        top: component.site.y,
        rotate: 0,
        //透明度
        opacity: 1,
        zIndex: component.site.z,
        perspective: false,
        // 隐藏
        hidden: false,
        // 锁定
        lock: false,
        classStyle: "",
        backgroundImage: component.site.backgroundImage
      },
      option: setting.option,
      key
    }
    component = g.Copy({
      ...item,
      ...component,
      ...{ optionSet }
    })
    component.option.horizontal = false
    component.option.label = {
      show: true,
      position: "top",
      distance: 5,
      rotate: 0,
      color: "",
      fontWeight: "normal",
      fontSize: 14,
      overflow: "break"
    }
    componentList.value.push(component)
  }
  // 删除组件
  const deleteComponent = () => {
    componentList.value = componentList.value.filter((item) => item.key !== currentComponent.value.key)
  }
  // 排序组件
  const sortComponent = () => {
    //排序
    componentList.value.forEach((item, index) => {
      item.element.zIndex = index + 1
    })
  }

  // 选中组件方法
  const selectComponent = (component) => {
    const { element } = { ...component }
    moveableReff.draggable = !element.lock
    moveableReff.resizable = !element.perspective
    moveableReff.warpable = element.perspective
    if (!component.data.source) {
      component.data.source = "cube"
      if (Router.currentRoute.value.query.cube_id) {
        component.data.cube_id = +Router.currentRoute.value.query.cube_id
      }
    }
    currentComponent.value = component
    moveableReff.target = [`.${component.key}`]
  }
  // 清空选中组件
  const clearComponent = () => {
    isBrush.value = false
    groupManager.value = []
    currentComponent.value = {
      data: {}
    }
  }

  // 撤销重做
  const recordHistory = useManualRefHistory(componentList, {
    capacity: 100
  })

  // 组合对齐方式
  const groupAlign = (type) => {
    // 等宽
    if (type === "width") {
      const rect = moveableReff.getRect()
      groupManager.value.forEach((item) => {
        const { element } = item
        element.width = rect.width
      })
    }
    // 等高
    if (type === "height") {
      const rect = moveableReff.getRect()
      groupManager.value.forEach((item) => {
        const { element } = item
        element.height = rect.height
      })
    }
    // 顶部对齐
    if (type === "top") {
      const rect = moveableReff.getRect()
      groupManager.value.forEach((item) => {
        const { element } = item
        element.top = rect.top
      })
    }
    // 底部对齐
    if (type === "bottom") {
      const rect = moveableReff.getRect()
      groupManager.value.forEach((item) => {
        const { element } = item
        element.top = rect.top + rect.height - element.height
      })
    }
    // 左对齐
    if (type === "left") {
      const rect = moveableReff.getRect()
      groupManager.value.forEach((item) => {
        const { element } = item
        element.left = rect.left
      })
    }
    // 右对齐
    if (type === "right") {
      const rect = moveableReff.getRect()
      groupManager.value.forEach((item) => {
        const { element } = item
        element.left = rect.left + rect.width - element.width
      })
    }
    // 水平居中
    if (type === "horizontal") {
      const rect = moveableReff.getRect()
      groupManager.value.forEach((item) => {
        const { element } = item
        element.left = rect.left + (rect.width - element.width) / 2
      })
    }
    // 垂直居中
    if (type === "vertical") {
      const rect = moveableReff.getRect()
      groupManager.value.forEach((item) => {
        const { element } = item
        element.top = rect.top + (rect.height - element.height) / 2
      })
    }
    // 等分分布
    if (type === "horizontal-distribution") {
      const rect = moveableReff.getRect()
      let left = rect.left
      // 总宽度
      const sumWidth = rect.children.reduce((prev, cur) => {
        return prev + cur.width
      }, 0)
      // 平均间隙
      let gap = parseInt((rect.width - sumWidth) / (rect.children.length - 1))
      if (gap < 0) gap = 0
      // 平均宽度
      const avgWidth = +(sumWidth / rect.children.length).toFixed(0)
      groupManager.value.sort((a, b) => {
        return a.element.left - b.element.left
      })
      groupManager.value.forEach((item) => {
        const { element } = item
        element.left = left
        element.width = +avgWidth
        left += element.width + gap
      })
    }
    // 垂直分布
    if (type === "vertical-distribution") {
      const rect = moveableReff.getRect()
      let top = rect.top
      // 总高度
      const sumHeight = rect.children.reduce((prev, cur) => {
        return prev + cur.height
      }, 0)
      // 平均间隙
      let gap = parseInt((rect.height - sumHeight) / (rect.children.length - 1))
      if (gap < 0) gap = 0
      // 平均高度
      const avgHeight = +(sumHeight / rect.children.length).toFixed(0)
      groupManager.value.sort((a, b) => {
        return a.element.top - b.element.top
      })
      groupManager.value.forEach((item) => {
        const { element } = item
        element.top = top
        element.height = +avgHeight
        top += element.height + gap
      })
    }
  }

  const prviewLoading = ref(false)
  const filterComponent = computed(() => {
    const filterComponent = componentList.value
      .filter((item) => item.name === "bi-search")
      .map((item) => {
        return item.option.query.map((v) => {
          Object.keys(v.component).forEach((key) => {
            v.component[key].data = {
              ...v.component[key].data,
              ...{
                query: {
                  filter: v.filter,
                  ...v.component[key].fieldQuery
                }
              }
            }
          })
          return v.component
        })
      })
    return filterComponent.flat(Infinity)
  })
  // 预览数据
  function previewData(currentComponent) {
    const current = g.Copy(currentComponent)
    const setting = settings.value[current.name]
    const dataParams = {
      datasource_id: current.data.datasource_id,
      cube_id: current.data.cube_id,
      fields: [],
      page_size: current.data.page_size || ""
    }
    Object.keys(setting.dataConfigOption).forEach((key) => {
      dataParams.fields = [...dataParams.fields, ...current.data[key]]
    })
    dataParams.sort = current.data.sort
    dataParams.filter = current.data.filter

    dataParams.filter.forEach((item) => {
      if (item.dataType.includes("yy") && item?.filter?.date && item?.filter?.filterForm === "1") {
        const startDate = item.filter.date.startDate
        const startDateTime = dayjs.operateDay(startDate.dateValue, startDate.dateRelative, startDate.dateType)
        const endDate = item.filter.date.endDate
        const endDateTime = dayjs.operateDay(endDate.dateValue, endDate.dateRelative, endDate.dateType)
        item.filter.filterCondition.value = [startDateTime, endDateTime]
      }
    })
    filterComponent.value
    current.data.query = []
    filterComponent.value.forEach((item) => {
      if (item[current.key] && item[current.key].checked) {
        current.data.query.push(item[current.key].data.query)
      }
    })
    dataParams.query = current.data.query
    if (dataParams.query) {
      // dataParams.query.forEach((item) => {
      //   if (item?.filter?.date) {
      //     const startDate = item.filter.date.startDate
      //     const startDateTime = dayjs.operateDay(startDate.dateValue, startDate.dateRelative, startDate.dateType)
      //     const endDate = item.filter.date.endDate
      //     const endDateTime = dayjs.operateDay(endDate.dateValue, endDate.dateRelative, endDate.dateType)
      //     item.filter.filterCondition.value = [startDateTime, endDateTime]
      //   }
      // })
    }
    if (dataParams.fields.length === 0) return
    prviewLoading.value = true
    cube.dataCubeComponentPreview(dataParams).then((res) => {
      const item = {
        list: res.data.data,
        columns: res.data.columns
      }
      item.data = arrReplaceKeys(res.data.data, res.data.columns)
      componentListRef[current.key].update(item)
      prviewLoading.value = false
    })
  }
  return {
    getComponent,
    componentList,
    currentComponent,
    addComponent,
    deleteComponent,
    sortComponent,
    selectComponent,
    clearComponent,
    recordHistory,
    groupManager,
    groupAlign,
    previewData,
    prviewLoading,
    componentListRef,
    resetComponent,
    importCompoent
  }
}

import { menusEvent } from "vue3-menus"
import { Message } from "@arco-design/web-vue"
import cube from "@/views/datasource/api/cube.js"
import { arrReplaceKeys, deepAssign } from "@/utils/util"
import { computed, ref } from "vue"
export const useMenus = () => {
  let curComponent = null
  let left = 0
  let top = 0
  // 右键菜单
  const menus = ref({
    menus: [
      {
        label: "上移一层",
        tip: "",
        hidden: false,
        click: (menu, arg) => {
          handleSelect("up", arg)
        }
      },
      {
        label: "下移一层",
        tip: "",
        hidden: false,
        click: (menu, arg) => {
          handleSelect("down", arg)
        }
      },
      {
        label: "置顶",
        tip: "",
        hidden: false,
        click: (menu, arg) => {
          handleSelect("top", arg)
        }
      },
      {
        label: "置底",
        tip: "",
        hidden: false,
        click: (menu, arg) => {
          handleSelect("bottom", arg)
        }
      },
      {
        label: "锁定",
        tip: "",
        hidden: false,
        click: (menu, arg) => {
          handleSelect("lock", arg)
        }
      },
      {
        label: "粘贴",
        tip: "",
        hidden: true,
        click: () => {
          handleSelect("paste")
        }
      },
      {
        label: "复制",
        tip: "（支持跨屏复制）",
        hidden: false,
        click: () => {
          handleSelect("copy")
        }
      },
      {
        label: "删除",
        tip: "",
        hidden: false,
        click: () => {
          handleSelect("del")
        }
      }
    ]
  })
  // 右键菜单点击事件
  const handleSelect = async (key) => {
    switch (key) {
      case "up":
        // 上移一层
        currentComponent.value.element.zIndex = currentComponent.value.element.zIndex + 1.5
        setTimeout(() => {
          componentList.value.sort((a, b) => {
            return a.element.zIndex - b.element.zIndex
          })
          useComponent().sortComponent()
        }, 100)
        break
      case "down":
        currentComponent.value.element.zIndex = currentComponent.value.element.zIndex - 1.5
        setTimeout(() => {
          componentList.value.sort((a, b) => {
            return a.element.zIndex - b.element.zIndex
          })
          useComponent().sortComponent()
        }, 100)
        break
      case "top":
        currentComponent.value.element.zIndex = componentList.value.length + 1
        setTimeout(() => {
          componentList.value.sort((a, b) => {
            return a.element.zIndex - b.element.zIndex
          })
          useComponent().sortComponent()
        }, 100)
        break
      case "bottom":
        currentComponent.value.element.zIndex = componentList.value[0].element.zIndex - 1
        setTimeout(() => {
          componentList.value.sort((a, b) => {
            return a.element.zIndex - b.element.zIndex
          })
          useComponent().sortComponent()
        }, 100)
        break
      case "lock":
        currentComponent.value.element.lock = !currentComponent.value.element.lock
        break
      case "paste":
        const component = JSON.parse(localStorage.getItem("copy_component"))
        if (!component.key) {
          Message.error("请先复制组件")
          return
        }
        curComponent = JSON.parse(JSON.stringify(component))
        curComponent.key = `${curComponent.name}-${g.guid(12)}`
        curComponent.element.left = left
        curComponent.element.top = top
        componentList.value.push(curComponent)
        break
      case "copy":
        localStorage.setItem("copy_component", JSON.stringify(currentComponent.value))
        break
      case "del":
        useComponent().deleteComponent()
        break
    }
  }

  function rightClick(event, item) {
    menus.value.menus.forEach((menu) => {
      menu.label === "粘贴" ? (menu.hidden = true) : (menu.hidden = false)
    })
    useComponent().selectComponent(item)
    menusEvent(event, menus.value)
  }

  function canvasClick(event) {
    menus.value.menus.forEach((menu) => {
      menu.label === "粘贴" ? (menu.hidden = false) : (menu.hidden = true)
    })
    left = event.offsetX
    top = event.offsetY
    menusEvent(event, menus.value)
  }

  return {
    menus,
    rightClick,
    canvasClick,
    handleSelect
  }
}

// 格式刷
const isBrush = ref(false)
const format = ref({})
export const useBrush = () => {
  const formatBrush = () => {
    format.value = currentComponent.value
    if (!currentComponent.value.key) {
      Message.info("请先选中组件", 2000)
      return false
    }
    isBrush.value = !isBrush.value
  }
  // 格式刷
  const formatBrushClick = (item) => {
    if (!isBrush.value) return
    item.option = format.value.option
  }
  return {
    isBrush,
    format,
    formatBrush,
    formatBrushClick
  }
}
